<?php
/**
 * Created by PhpStorm.
 * User: Administratorjing
 * Date: 2018/7/29/029
 * Time: 15:58
 * By Hedy<714195347@qq.com>
 */

namespace App\Http\Controllers;


use App\Exceptions\InvalidRequestException;
use App\Http\Requests\Request;
use App\Models\Order;
use Carbon\Carbon;
use Endroid\QrCode\QrCode;
use App\Events\OrderPaid;
class PaymentController extends Controller
{
    public function payByAlipay(Order $order,Request $request)
    {
        //判断当前订单是否属于当前用户
        $this->authorize('own',$order);
        //订单已支付或者已经支付
        if($order->paid_at||$order->closed){
            throw new InvalidRequestException('订单状态不正确');
        }
        //调用支付宝的网页支付
        return app('alipay')->web([
            'out_trade_no' => $order->no,//订单编号，需保证在商户端不重复
            'total_amount' => $order->total_amount,//订单金额，单位元，支持小数点后两位
            'subject'      => '支付Hedy的订单：'.$order->no,//订单标题
        ]);
    }

    /**
     * 前端回调
     */
    public function alipayReturn()
    {
        //效验参数是否正确
        //app('alipay')->verify() 用于校验提交的参数是否合法，支付宝的前端跳转会带有数据签名，通过校验数据签名可以判断参数是否被恶意用户篡改。同时该方法还会返回解析后的参数。
       try{
           app('alipay')->verify();
       }catch (\Exception $e){
           return view('pages.error',['msg'=>'数据不正确']);
       }
       return view('pages.success',['msg'=>'付款成功']);
    }
    public function alipayNotify()
    {
        //\Log::debug('Alipay notify', $data->all()); 由于服务器端的请求我们无法看到返回值，使用 dd 就不行了，所以需要通过日志的方式来保存。
        $data = app('alipay')->verify();
        //拿到订单流水号，并在数据库中查询
        $order = Order::where('no',$data->out_trade_no)->first();
        if(!$order){
            return 'fail';
        }
        //已支付
        if($order->paid_at){
            //返回数据给支付宝
            return app('alipay')->success();
        }
        $order->update([
            'paid_at'   =>Carbon::now(),//支付时间
            'payment_method' => 'alipay',//支付方式
            'payment_no'  => $data->trade_no,//支付宝订单号
        ]);
        //\Log::debug('Alipay notify',$data->all());

        //触发回调事件
        $this->afterPaid($order);
        return app('alipay')->success();
    }

    //微信支付
    public function payByWechat(Order $order,Request $request)
    {
        //效验权限
        $this->authorize('own',$order);
        //检查订单状态
        if($order->paid_at||$order->closed){
            throw new InvalidRequestException('订单状态不正确');
        }
        // scan 方法为拉起微信扫码支付
        return app('wechat_pay')->scan([
            'out_trade_no' => $order->no,  // 商户订单流水号，与支付宝 out_trade_no 一样
            'total_fee' => $order->total_amount * 100, // 与支付宝不同，微信支付的金额单位是分。
            'body'      => '支付 Laravel Shop 的订单：'.$order->no, // 订单描述
        ]);
        // 把要转换的字符串作为 QrCode 的构造函数参数
        $qrCode = new QrCode($wechatOrder->code_url);

        // 将生成的二维码图片数据以字符串形式输出，并带上相应的响应类型
        return response($qrCode->writeString(), 200, ['Content-Type' => $qrCode->getContentType()]);
    }

    //微信回调接口，没有前端回调只有服务器端回调
    public function wechatNotify()
    {
        //检查回调参数是否正确
        $data = app('wechat_pay')->verify();
        //找到对应的订单
        $order = Order::where('no',$data->out_trade_no)->first();
        //若订单不存在
        if(!$order){
            return 'fail';
        }
        //订单已经支付
        if($order->paid_at){
            return app('wechat_pay')->success();
        }
        //将订单标记为已支付
        $order->update([
            'paid_at'        => Carbon::now(),
            'payment_method' => 'wechat',
            'payment_no'     => $data->transaction_id,
        ]);
        $this->afterPaid($order);
        return app('wechat_pay')->success();
    }

    //销量
    protected function afterPaid(Order $order)
    {
        event(new OrderPaid($order));
    }

}